﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using MagicKey.Components.FileAccess;
using MagicKey.Components.UserManager;
using MagicKey.Factory;
using MagicKey.Interfaces;
using Microsoft.Win32;
using MessageBox = System.Windows.MessageBox;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;

namespace MagicKey.UserInterface
{
    /// <summary>
    /// Interaktionslogik für Fileviewer.xaml
    /// </summary>
    public partial class Fileviewer : Window
    {
        #region Fields

        private static readonly IMagicKey MagicKey = MagicKeyFactory.GetInstance().GetMagicKeyInterface();
        private readonly MainWindow _mainWindow;
        private ManageAuthorizations _manageAuthorizations;
        private IUserManager _userManager = MagicKey.GetUserManager();
        private User masterUser; // The current user
        private User superUser; // The user to restore data
        private IFileAccess _fileAccess;
        private IMagicKey _magicKey;
        private List<string> _filesList;
        private List<User> allUsers;
        private bool isSelectedFileDecrypt = false;
        private string selectedFile;

        #endregion

        #region Constructors

        public Fileviewer(MainWindow myWindow)
        {
            InitializeComponent();

            // The following line enables the tremble effect for the current
            // window when clicking on the main window
            this.Owner = myWindow;

            _mainWindow = myWindow;
            this.masterUser = new User();
            masterUser.Name = _mainWindow.MasterUser;
            this.CurrentUserLabel.Content += " " + masterUser.Name + " !";

            var factory = _mainWindow.Factory;
            _magicKey = factory.GetMagicKeyInterface();
            _fileAccess = _magicKey.GetFileAccess();

            RefreshfileList();
        }

        #endregion Constructors

        #region Properties

        public string SelectedFile
        {
            get
            {
                return this.selectedFile;
            }

            set
            {
                this.selectedFile = value;
            }
        }

        public bool IsSelectedFileDecrypt
        {
            get
            {
                return this.isSelectedFileDecrypt;
            }

            set
            {
                this.isSelectedFileDecrypt = value;
            }
        }

        public User MasterUser
        {
            get
            {
                return this.masterUser;
            }

            set
            {
                this.masterUser = value;
            }
        }
        public User SuperUser
        {
            get
            {
                return this.superUser;
            }

            set
            {
                this.superUser = value;
            }
        }


        public List<User> AllUsers
        {
            get
            {
                return this.allUsers;
            }

            set
            {
                this.allUsers = value;
            }
        }
        #endregion

        #region Methods

        public void RefreshfileList()
        {
            bool isMaFound = false;
            bool isSupFound = false;
            this._userManager.LoadAllUsers();

            allUsers = ((UserManager)this._userManager).Users;

            this._filesList = new List<string>();

            foreach (User u in allUsers)
            {
                if (u.Name.Equals(masterUser.Name))
                {
                    this.masterUser = u;
                    foreach (string s in u.MyFiles)
                    {
                        this._filesList.Add(s);
                    }

                    foreach (string s in u.OtherUserFiles)
                    {
                        this._filesList.Add(s);
                    }
                    isMaFound = true;
                }
                else if (u.Name.Equals("ControlChief"))
                {
                    this.superUser = u;
                    isSupFound = true;
                }

                if (isMaFound && isSupFound)
                {
                    break;
                }
            }

            this.FileListBox.ItemsSource = this._filesList;
        }

        #endregion Methods

        #region EventChangedMethods

        private void FileListBox_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            SelectedFile = (string)this.FileListBox.SelectedItem;
            var pv = new PasswordViewer(this);

            bool? rsp = pv.ShowDialog();

            if (rsp == true)
            {
                if (isSelectedFileDecrypt)
                {
                   //TODO
                }
            }
        }
        private void LoadDocumentButton_Click(object sender, RoutedEventArgs e)
        {

            // Open document
            var accessManager = _magicKey.GetAccessManager();

            // Create OpenFileDialog
            var openFileDialog = new OpenFileDialog
            {
                //// Set filter for file extension
                //DefaultExt = ".txt",
                //// default file extension
                //Filter = "Text documents (.txt)|*.txt"
            };


            // Display OpenFileDialog by calling ShowDialog method
            var result = openFileDialog.ShowDialog();

            // Get the selected file name and display in a TextBox
            if (result != true) return;

            var localFileSymEncrpted = accessManager.EncryptFileSym(openFileDialog.FileName, _userManager.GetUserSymetricKey(masterUser.Name));
            var localFileSymEncrpted2 = accessManager.EncryptFileSym(openFileDialog.FileName, _userManager.GetUserSymetricKey(masterUser.Name));

            var localFileASymEncrpted = accessManager.EncryptFileAsym(masterUser.Name, localFileSymEncrpted);
            
            //build path on server and upload files
            var file = new FileInfo(openFileDialog.FileName);
            var ftpHelper = new FtpHelper();
            string pathOnServer = ftpHelper.SetUri(file.Name);
            //var localFileAsymEncrptedDb2 = accessManager.EncryptFileAsym(pathOnServer, thissuperUser.PublicKey);

            string filename = _fileAccess.UploadFile(localFileASymEncrpted, pathOnServer, masterUser.Id);

            // Important 
            GC.Collect();
            GC.WaitForPendingFinalizers();

            File.Delete(localFileSymEncrpted);
            File.Delete(localFileASymEncrpted);
            //File.Delete(localFileAsymEncrptedDb2);
            //---------------------------------- Insert the file in the d.atabase

            if (!filename.Equals(string.Empty))
            {
                // Refresh the file listbox
                RefreshfileList();
            }
        }

        private void ManageAuthorizationsButton_Click(object sender, RoutedEventArgs e)
        {
            _manageAuthorizations = new ManageAuthorizations(this);
            _manageAuthorizations.Show();
        }

        private void FileListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

            if (this.FileListBox.SelectedIndex != -1)
            {
                // A file has been selected!

                string selectedFile = (string)this.FileListBox.SelectedItem;

                string ownerName = _userManager.GetOwnerName(selectedFile);

                this.FileOwnerLabel.Content = "File owner: " + ownerName;

                if (ownerName.Equals(masterUser.Name))
                {
                    this.DeleteFileButton.IsEnabled = true;
                    this.ManageAuthorizationsButton.IsEnabled = true;
                }
                else
                {
                    this.DeleteFileButton.IsEnabled = false;
                    this.ManageAuthorizationsButton.IsEnabled = false;
                }

            }
            else
            {
                this.DeleteFileButton.IsEnabled = false;
                this.ManageAuthorizationsButton.IsEnabled = false;
            }
        }

        private void DeleteFileButton_Click(object sender, RoutedEventArgs e)
        {
            //Check if current user is a Owner
            int selectedIndex = this.FileListBox.SelectedIndex;
            string selectedFile = (string)this.FileListBox.SelectedItem;

            if (this.masterUser.MyFiles.Contains(selectedFile))
            {
                if (_fileAccess.DeleteFile(selectedFile, this.masterUser.Id))
                {
                    this._filesList.RemoveAt(selectedIndex);
                    this.RefreshfileList();
                }
            }
            else
            {
                MessageBox.Show("You cannot access this file!", "Fileviewer",
                                      MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }

        private void Fileviewer_OnClosing(object sender, CancelEventArgs e)
        {
            string msg = "Do you really want to logout?";
            MessageBoxResult result = MessageBox.Show(msg, "Fileviewer",
                                      MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (result == MessageBoxResult.No)
            {
                // If user doesn't want to close, cancel closure
                e.Cancel = true;
            }
            else
            {
                ((MainWindow)this.Owner).Init();
                e.Cancel = false;
            }
        }

        #endregion EventChangedMethods

        private void Logout_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }


    }
}
